package org.finesys.common.security.client.http;

import java.io.IOException;
import java.security.Principal;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.finesys.common.security.client.core.constants.GiteeEndpointConstants;
import org.finesys.common.security.client.core.constants.GiteeScopeEnum;
import org.finesys.common.security.client.service.GiteeRegisteredClientRepository;
import org.finesys.common.security.core.module.AuthUser;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.util.StringUtils;

import cn.hutool.core.text.StrPool;
import lombok.RequiredArgsConstructor;


@RequiredArgsConstructor
public class GiteeAuthorizeHttpFilter implements Filter {


    private final GiteeRegisteredClientRepository giteeRegisteredClientRepository;
    private final OAuth2AuthorizationService oAuth2AuthorizationService;
    public static final String PREFIX_URL = "/gitee/authorize";

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        String uri = httpServletRequest.getRequestURI();
        //码云配置的appId
        String appId = uri.replace(PREFIX_URL + StrPool.COLON, "");
        //重定向地址
        String redirectURI = giteeRegisteredClientRepository.getRedirectURIByAppId(appId);
        //授权的scope
        String scope = httpServletRequest.getParameter(OAuth2ParameterNames.SCOPE);
        //accessToken
        String accessToken = httpServletRequest.getParameter(OAuth2ParameterNames.ACCESS_TOKEN);

        String scopeRes;
        if (Objects.isNull(scope)) {
            scopeRes = GiteeScopeEnum.USER_INFO.getValue();
        } else {
            List<String> scopes = Arrays.asList(StringUtils.delimitedListToStringArray(scope, StrPool.COMMA));
            scopes.retainAll(GiteeScopeEnum.legalScope());
            scopeRes = String.join(StrPool.COMMA, new HashSet<>(scopes));
        }
        //生成一个状态码
        String state = giteeRegisteredClientRepository.stateGenerate(appId);
        if (StringUtils.hasText(accessToken)) {
            AuthUser authUser =null;
            OAuth2Authorization auth2Authorization=oAuth2AuthorizationService.findByToken(accessToken, OAuth2TokenType.ACCESS_TOKEN);
            if(auth2Authorization!=null){
                authUser = (AuthUser) ((UsernamePasswordAuthenticationToken)auth2Authorization.getAttributes().get(Principal.class.getName())).getPrincipal();
            }
            //标记操作用户
            if (Objects.nonNull(authUser)) {
                giteeRegisteredClientRepository.tagUsers(appId, state, authUser.getUserId());
            }
        }
        String url = String.format(GiteeEndpointConstants.AUTHORIZE_URL, appId, redirectURI, scopeRes, state);
        httpServletResponse.sendRedirect(url);
    }
}
